#include "Excutor.hpp"
#include "Paser.hpp"
#include "Tool.hpp"
#include "../base/Defind.hpp"
#include <utility>

using namespace DBServer::Database;

static void timeout(CommandRespond& rep)
{
    rep.respond = TIMEOUT;
}

auto Excutor::excute(Object& o, CommandRespond& rep, CommandRequest&& req, com_func_t& cft) -> int
{   
    // check the key is expire
    if (o.timeout())
    {
        timeout(rep);
        return ERR_TIMEOUT;
    }
    o.command_excute(rep, std::move(req), cft);
    return ERR_NORMAL;
}

auto Excutor::excute_commen(Object& o, CommandRespond& rep, CommandRequest&& req, com_func_t& cft) -> int
{   
    // check the key is expire
    if (o.timeout())
    {
        timeout(rep);
        return ERR_TIMEOUT;
    }
    cb_table[cft.second](*this, o, std::move(req), rep);
    return ERR_NORMAL;
}

auto Excutor::ttl(Object& oo, unsigned long long expire) -> bool
{
    oo.set_expire(expire);
    return true;
}

auto Excutor::type(Object& oo) -> std::string
{
    return oo.get_type();
}

auto Excutor::alive(Object& oo) -> unsigned long long
{
    return oo.get_expire();
}


/**----------------------------------------------
 * 
 * initalize the class number
 * 
 * -----------------------------------------------
*/
using CallBack = std::function<void(Excutor& ex, Object&, CommandRequest&&, CommandRespond&)>;

// initial the for hash map
std::unordered_map<int, CallBack> Excutor::cb_table([](){
    std::unordered_map<int, CallBack> temp;
    temp[TTL] = [](Excutor& ex, Object& oo, CommandRequest&& crq, CommandRespond& crp){
        auto ret = ex.ttl(oo, Translator::string_to_int(crq.command[COMMAND_VALUE]));
        crp.respond = OK;
    };
    temp[TYPE] = [](Excutor& ex, Object& oo, CommandRequest&& crq, CommandRespond& crp){
        auto ret = ex.type(oo);
        crp.respond = ret;
    };
    temp[ALIVE] = [](Excutor& ex, Object& oo, CommandRequest&& crq, CommandRespond& crp){
        auto ret = ex.alive(oo);
        crp.respond = Translator::int_to_string(ret);
    };
    return temp;
}());